#include "login.h"
#include "ui_login.h"
#include"protocol.h"
#include"mainwindow.h"
#include <QMouseEvent>
#include<QHostAddress>
#include<QDebug>
#include<QMessageBox>
#include"friendwindow.h"


login::login(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::login)
{
    ui->setupUi(this);
    this->setWindowFlags(Qt::SplashScreen|Qt::WindowStaysOnTopHint|Qt::FramelessWindowHint);
    ui->le_name->setPlaceholderText("请输入账号");
    ui->le_pwd->setPlaceholderText("请输入密码");
    m_strIP="127.0.0.1";
    m_usPort=8888;
    m_tcpSocket.connectToHost(QHostAddress(m_strIP),m_usPort);
    connect(&m_tcpSocket,SIGNAL(connected()),this,SLOT(showConncet()));
    connect(&m_tcpSocket, SIGNAL(readyRead()), this, SLOT(receiveMsg()));
}

login::~login()
{
    delete ui;
}

void login::mousePressEvent(QMouseEvent *event)
{
    auto rect = ui->title->geometry();
    auto p= event->pos();
    if(rect.contains(p))
    {
         m_isPressed = true;
         m_wnd = this ->geometry().topLeft();
         press = this ->mapToGlobal(p);
    }
}

void login::mouseReleaseEvent(QMouseEvent *event)
{
    m_isPressed = false;
}

void login::mouseMoveEvent(QMouseEvent *event)
{
    if(m_isPressed)
    {
       auto v = mapToGlobal(event->pos())-press;
       auto r = m_wnd;
       this ->move(r+v);
    }
}

login &login::getInstance()
{
    static login instance;
    return instance;
}

QTcpSocket &login::getTcpSocket()
{
    return m_tcpSocket;
}

QString login::getStrName() const
{
    return m_strName;
}

void login::setStrName(const QString &strName)
{
    m_strName = strName;
}

QString login::getStrRootPath() const
{
    return m_strRootPath;
}

void login::setStrRootPath(const QString &strRootPath)
{
    m_strRootPath = strRootPath;
}

QString login::getStrCurPath() const
{
    return m_strCurPath;
}

void login::setStrCurPath(const QString &strCurPath)
{
    m_strCurPath = strCurPath;
}

void login::showConncet()
{
    qDebug() << "连接服务器成功";
}

void login::receiveMsg()
{


    // 如果处于接收文件数据的状态
    TransFile *transFile = MainWindow::getInstance().getFileWindow()->getDownloadFileInfo();
    if(transFile->bTransform)
    {
        QByteArray baBuffer = m_tcpSocket.readAll();
        transFile->file.write(baBuffer);

        transFile->iReceivedSize += baBuffer.size();
        if(transFile->iReceivedSize == transFile->iTotalSize)
        {

            QMessageBox::information(this, "下载文件", "下载文件成功！");
            transFile->file.close();
            transFile->file.setFileName("");
            transFile->bTransform = false;
            transFile->iTotalSize = 0;
            transFile->iReceivedSize = 0;
        }
        else if(transFile->iReceivedSize > transFile->iTotalSize)
        {
            QMessageBox::warning(this, "下载文件", "下载文件失败！");
            transFile->file.close();
            transFile->file.setFileName("");
            transFile->bTransform = false;
            transFile->iTotalSize = 0;
            transFile->iReceivedSize = 0;
        }
        return ;
    }


    // 否则，处理其他响应PDU
    qDebug() << m_tcpSocket.bytesAvailable();
    uint uiPDULen = 0;
    m_tcpSocket.read((char*)&uiPDULen, sizeof(uint));
    uint uiMsgLen = uiPDULen - sizeof(PDU);
    PDU *pdu = mkPDU(uiMsgLen);
    m_tcpSocket.read((char*)pdu + sizeof(uint), uiPDULen - sizeof(uint));
    switch(pdu -> uiMsgType)
    {
    case ENUM_MSG_TYPE_REGIST_RESPOND:
    {
        if(0 == strcmp(pdu -> caData, REGIST_OK))
        {
            QMessageBox::information(this, "注册", REGIST_OK);
        }
        else if(0 == strcmp(pdu -> caData, REGIST_FAILED))
        {
            QMessageBox::warning(this, "注册", REGIST_FAILED);
        }
        break;
    }
    case ENUM_MSG_TYPE_LOGIN_RESPOND:
    {
        if(0 == strcmp(pdu -> caData, LOGIN_OK))
        {
            char caName[32] = {'\0'};
            strncpy(caName, pdu -> caData + 32, 32);
            m_strName = caName;
            m_strRootPath = QString((char*)pdu -> caMsg);
            m_strCurPath = m_strRootPath;

            qDebug() << "用户已登录：" << caName << " strName：" << m_strName;
            MainWindow::getInstance().setUserLabel(caName);
            MainWindow::getInstance().show();

            this -> hide(); // 隐藏登陆页面
        }
        else if(0 == strcmp(pdu -> caData, LOGIN_FAILED))
        {
            QMessageBox::warning(this, "登录", LOGIN_FAILED);
        }
        break;
    }
    case ENUM_MSG_TYPE_ONLINE_USERS_RESPOND:
    {
        MainWindow::getInstance().getPFriend() -> setOnlineUsers(pdu);
        break;
    }
    case  ENUM_MSG_TYPE_ADD_FRIEND_RESPOND:
    {
       QMessageBox::information(this, "添加好友", pdu -> caData);
        break;
    }
    case ENUM_MSG_TYPE_ADD_FRIEND_REQUEST:
    {
        char sourceName[32]; // 获取发送方用户名
        strncpy(sourceName, pdu -> caData + 32, 32);
        int ret = QMessageBox::information(this, "好友申请", QString("%1 想添加您为好友，是否同意？").arg(sourceName),
                                 QMessageBox::Yes, QMessageBox::No); // 后面两个参数是为QMessage默认支持两个按钮来设置枚举值
        PDU* resPdu = mkPDU(0);

        strncpy(resPdu -> caData, pdu -> caData, 32); // 被加好友者用户名
        strncpy(resPdu -> caData + 32, pdu -> caData + 32, 32); // 加好友者用户名
        // qDebug() << "同意加好友吗？" << resPdu -> caData << " " << resPdu -> caData + 32;
        if(ret == QMessageBox::Yes) // 同意加好友
        {
            resPdu->uiMsgType = ENUM_MSG_TYPE_ADD_FRIEND_AGREE;
        }
        else
        {
            resPdu->uiMsgType = ENUM_MSG_TYPE_ADD_FRIEND_REJECT;
        }
        m_tcpSocket.write((char*)resPdu, resPdu -> uiPDULen); // 发送给服务器消息，由服务器写入数据库并转发给用户

        break;
    }
    case ENUM_MSG_TYPE_ADD_FRIEND_AGREE: // 对方同意加好友
    {
        QMessageBox::information(this, "添加好友", QString("%1 已同意您的好友申请！").arg(pdu -> caData));
        break;
    }
    case ENUM_MSG_TYPE_ADD_FRIEND_REJECT: // 对方拒绝加好友
    {
        QMessageBox::information(this, "添加好友", QString("%1 已拒绝您的好友申请！").arg(pdu -> caData));
        break;
    }
    case ENUM_MSG_TYPE_FLUSH_FRIEND_RESPOND:// 刷新好友响应
    {
       MainWindow::getInstance().getPFriend()->updateFriendList(pdu);
        break;
    }
    case ENUM_MSG_TYPE_DELETE_FRIEND_RESPOND: // 删除好友响应
    {   QApplication::setQuitOnLastWindowClosed(false);
        QMessageBox::information(this, "删除好友", pdu -> caData);
        break;
    }
    case ENUM_MSG_TYPE_DELETE_FRIEND_REQUEST: // 处理服务器转发过来的删除好友请求
    {   QApplication::setQuitOnLastWindowClosed(false);
        char sourceName[32];
        strncpy(sourceName, pdu -> caData + 32, 32);
        QMessageBox::information(this, "删除好友", QString("%1 已删除与您的好友关系！").arg(sourceName));
        break;
    }
    case ENUM_MSG_TYPE_PRIVATE_CHAT_RESPOND: // 私聊好友消息响应（发送消息是否成功）
    {
        if(strcmp(PRIVATE_CHAT_OFFLINE, pdu -> caData) == 0)
        {
            QMessageBox::information(this, "私聊", PRIVATE_CHAT_OFFLINE);
        }
        break;
    }
    case ENUM_MSG_TYPE_PRIVATE_CHAT_REQUEST: // 私聊好友消息请求（接收消息）
    {
        {
            char sourceName[32] = {'\0'};
            strncpy(sourceName, pdu->caData + 32, 32);
            sourceName[31] = '\0';

            char strSendMsg[256] = {'\0'};
            memcpy(strSendMsg, pdu->caMsg, pdu->uiMsgLen);
            strSendMsg[pdu->uiMsgLen] = '\0';
  //          qDebug() << "Received message from:" << sourceName << "Message:" << strSendMsg;
            FriendWindow* friendWindow = MainWindow::getInstance().getPFriend();
               if (friendWindow != nullptr) {
                   friendWindow->sayFriendList(pdu);
               }

            break;
        }
        break;
    }
    case ENUM_MSG_TYPE_CREATE_DIR_RESPOND: // 创建文件夹响应
       {
           QMessageBox::information(this, "创建文件夹", pdu -> caData);
           break;
       }
       case ENUM_MSG_TYPE_FLUSH_DIR_RESPOND://刷新文件
       {
           MainWindow::getInstance().getFileWindow()->updateFileList(pdu);
           break;
       }
       case ENUM_MSG_TYPE_DELETE_FILE_RESPOND: // 删除文件或文件夹响应
       {
           QMessageBox::information(this, "删除文件", pdu -> caData);
           break;
       }
       case ENUM_MSG_TYPE_RENAME_FILE_RESPOND: // 重命名文件或文件夹响应
       {
           QMessageBox::information(this, "重命名文件", pdu -> caData);
           break;
       }
       case ENUM_MSG_TYPE_ENTRY_DIR_RESPOND: // 进入文件夹响应
       {
           qDebug() << "进入文件夹响应：" << pdu -> caData;
           if(strcmp(ENTRY_DIR_OK, pdu -> caData) == 0)
           {
               MainWindow::getInstance().getFileWindow() -> updateFileList(pdu); // 刷新文件列表
               QString entryPath = MainWindow::getInstance().getFileWindow()->strTryEntryDir();
               if(!entryPath.isEmpty())
               {
                   m_strCurPath = entryPath;
                   MainWindow::getInstance().getFileWindow()->clearStrTryEntryDir(); // 清空m_strTryEntryDir
                   qDebug() << "当前路径：" << m_strCurPath;
               }
           }
           else
           {
               QMessageBox::warning(this, "进入文件夹", pdu -> caData);
           }
           break;
       }
       case ENUM_MSG_TYPE_PRE_DIR_RESPOND: // 上一目录响应
       {
           qDebug() << "上一文件夹响应：" << pdu -> caData;
           if(strcmp(PRE_DIR_OK, pdu -> caData) == 0)
           {
               MainWindow::getInstance().getFileWindow() -> updateFileList(pdu); // 刷新文件列表
               QString entryPath = MainWindow::getInstance().getFileWindow()->strTryEntryDir();
               if(!entryPath.isEmpty())
               {
                   m_strCurPath = entryPath;
                   MainWindow::getInstance().getFileWindow()->clearStrTryEntryDir(); // 清空m_strTryEntryDir
                   qDebug() << "当前路径：" << m_strCurPath;
               }
           }
           else
           {
               QMessageBox::warning(this, "上一文件夹", pdu -> caData);
           }
           break;
       }
    case ENUM_MSG_TYPE_UPLOAD_FILE_RESPOND: // 上传文件响应
            {
            qDebug() <<pdu -> caData;
            if(strcmp(UPLOAD_FILE_START, pdu -> caData) == 0) // 开始上传文件数据内容
            {
                qDebug() <<"跳转前";
                MainWindow::getInstance().getFileWindow()->startTimer();
                qDebug() <<"跳转后";
            }
            else if(strcmp(UPLOAD_FILE_OK, pdu -> caData) == 0) // 上传文件成功
            {
                QMessageBox::information(this, "上传文件", pdu -> caData);
            }
            else if(strcmp(UPLOAD_FILE_FAILED, pdu -> caData) == 0) // 上传失败
            {
                QMessageBox::warning(this, "上传文件", pdu -> caData);
            }
            break;
            }
    case ENUM_MSG_TYPE_DOWNLOAD_FILE_RESPOND: // 下载文件响应
    {
        if(strcmp(DOWNLOAD_FILE_START, pdu -> caData) == 0) // 开始下载文件数据内容
        {
            // TransFile *transFile = OperateWidget::getInstance().getPFileSystem()->getDownloadFileInfo();
            qint64 ifileSize = 0;
            char strFileName[32];
            sscanf((char*)pdu -> caMsg, "%s %lld", strFileName, &ifileSize);
            qDebug() << "下载文件中：" << strFileName << ifileSize;

            if(strlen(strFileName) > 0 && transFile->file.open(QIODevice::WriteOnly))
            {
                transFile->bTransform = true;
                transFile->iTotalSize = ifileSize;
                transFile->iReceivedSize = 0;
            }
            else
            {
                QMessageBox::warning(this, "下载文件", "下载文件失败！");
            }
        }
        else if(strcmp(DOWNLOAD_FILE_OK, pdu -> caData) == 0) // 下载文件成功
        {
            QMessageBox::information(this, "下载文件", pdu -> caData);
        }
        else if(strcmp(DOWNLOAD_FILE_FAILED, pdu -> caData) == 0) // 下载失败
        {
            QMessageBox::warning(this, "下载文件", pdu -> caData);
        }
        break;
    }

    default:
        break;
    }
    free(pdu);
    pdu=NULL;
}

void login::on_toolButton_clicked()
{
    showMinimized();
}

void login::on_toolButton_2_clicked()
{
    exit(0);
}

void login::on_bnt_login_clicked()
{
    QString strName = ui->le_name->text();
    QString strPwd = ui->le_pwd->text();
    if(!strName.isEmpty()&&!strPwd.isEmpty())
    {
        PDU *pdu = mkPDU(0);
        pdu -> uiMsgType = ENUM_MSG_TYPE_LOGIN_REQUEST;
        memcpy(pdu -> caData, strName.toStdString().c_str(), 32);
        memcpy(pdu -> caData + 32, strPwd.toStdString().c_str(), 32);
        qDebug() << pdu -> uiMsgType << " " << pdu -> caData << " " << pdu -> caData + 32;
        m_tcpSocket.write((char*)pdu, pdu -> uiPDULen);
        free(pdu);
        pdu = NULL;
    }else{
        QMessageBox::critical(this, "登录", "登录失败：用户名或密码为空！");
    }
}

void login::on_btn_register_clicked()
{
    QString strName = ui->le_name->text();
    QString strPwd = ui->le_pwd->text();
    if(!strName.isEmpty()&&!strPwd.isEmpty())
    {
        PDU *pdu = mkPDU(0);
        pdu -> uiMsgType = ENUM_MSG_TYPE_REGIST_REQUEST;
        memcpy(pdu -> caData, strName.toStdString().c_str(), 32);
        memcpy(pdu -> caData + 32, strPwd.toStdString().c_str(), 32);
        qDebug() << pdu -> uiMsgType << " " << pdu -> caData << " " << pdu -> caData + 32;
        m_tcpSocket.write((char*)pdu, pdu -> uiPDULen);
        free(pdu);
        pdu = NULL;
    }else{
        QMessageBox::critical(this, "注册", "注册失败：用户名或密码为空！");
    }
}
